--{{{ Libraries

local RL -- only loaded in OnEnable when used with non-guid Grid now:    = AceLibrary("Roster-2.1")
local L = AceLibrary("AceLocale-2.2"):new("GridStatusPWShield")

--}}}

local playerClass, englishClass = UnitClass("player")

local spellNameCache = {};
spellNameCache.PWShield = GetSpellInfo(17);
spellNameCache.WeakenedSoul = GetSpellInfo(6788);
GridStatusPWShield = GridStatus:NewModule("GridStatusPWShield")
GridStatusPWShield.menuName = L["PWShield"];

GridStatusPWShield.extraOptions = {
	["frequency"] = {
		type = 'range',
		name = L["Refresh frequency"],
		desc = L["Seconds between status refreshes"],
		get = function() return GridStatusPWShield.db.profile.frequency end,
		set = function(v)
				  GridStatusPWShield.db.profile.frequency = v
				  GridStatusPWShield:UpdateFrequency()
			  end,
		min = 0.01,
		max = 1,
		step = 0.01,
		isPercent = false,
		order = -1,
	},
}


--{{{ AceDB defaults
--
GridStatusPWShield.defaultDB = {
	frequency = 0.5,
	alert_pws = {
		text = L["Buff: My Power Word: Shield"],
		desc = L["Buff: My Power Word: Shield"],
		enable = true,
		priority = 99,
		range = false,
		threshold2 = 4,
		threshold3 = 2,
		color = { r = 1, g = 1, b = 0, a = 1 },
		color2 = { r = 1, g = 1, b = 0, a = 1 },
		color3 = { r = 1, g = 0, b = 0, a = 1 },		
	},
	alert_ws = {
		text = L["Debuff: My Weakened Soul"],
		desc = L["Debuff: My Weakened Soul"],
		enable = true,
		priority = 97,
		range = false,
		threshold2 = 4,
		threshold3 = 2,
		color = { r = 0.5, g = 0.5, b = 0.5, a = 1 },
		color2 = { r = 0.5, g = 0.5, b = 0.5, a = 1 },
		color3 = { r = 1, g = 0, b = 0, a = 1 },		
	},
}

local pws_options = {
	["threshold2"] = {
		type = "range",
		name = L["Threshold to activate color 2"],
		desc = L["Threshold to activate color 2"],
		max = 10,
		min = 1,
		step = .5,
		get = function ()
			return GridStatusPWShield.db.profile.alert_pws.threshold2
		end,
		set = function (v)
			GridStatusPWShield.db.profile.alert_pws.threshold2 = v
		end,
	},
	["color2"] = {
		type = "color",
		name = L["Color 2"],
		desc = L["Color 2"],
		hasAlpha = true,
		get = function ()
			local color = GridStatusPWShield.db.profile.alert_pws.color2
			return color.r, color.g, color.b, color.a
		end,
		set = function (r, g, b, a)
			local color = GridStatusPWShield.db.profile.alert_pws.color2
			color.r = r
			color.g = g
			color.b = b
			color.a = a or 1
		end,
	},
	["threshold3"] = {
		type = "range",
		name = L["Threshold to activate color 3"],
		desc = L["Threshold to activate color 3"],
		max = 10,
		min = 1,
		step = .5,
		get = function ()
			return GridStatusPWShield.db.profile.alert_pws.threshold3
		end,
		set = function (v)
			GridStatusPWShield.db.profile.alert_pws.threshold3 = v
		end,
	},
	["color3"] = {
		type = "color",
		name = L["Color 3"],
		desc = L["Color 3"],
		hasAlpha = true,
		get = function ()
			local color = GridStatusPWShield.db.profile.alert_pws.color3
			return color.r, color.g, color.b, color.a
		end,
		set = function (r, g, b, a)
			local color = GridStatusPWShield.db.profile.alert_pws.color3
			color.r = r
			color.g = g
			color.b = b
			color.a = a or 1
		end,
	},
}

local ws_options = {
	["threshold2"] = {
		type = "range",
		name = L["Threshold to activate color 2"],
		desc = L["Threshold to activate color 2"],
		max = 10,
		min = 1,
		step = .5,
		get = function ()
			return GridStatusPWShield.db.profile.alert_ws.threshold2
		end,
		set = function (v)
			GridStatusPWShield.db.profile.alert_ws.threshold2 = v
		end,
	},
	["color2"] = {
		type = "color",
		name = L["Color 2"],
		desc = L["Color 2"],
		hasAlpha = true,
		get = function ()
			local color = GridStatusPWShield.db.profile.alert_ws.color2
			return color.r, color.g, color.b, color.a
		end,
		set = function (r, g, b, a)
			local color = GridStatusPWShield.db.profile.alert_ws.color2
			color.r = r
			color.g = g
			color.b = b
			color.a = a or 1
		end,
	},
	["threshold3"] = {
		type = "range",
		name = L["Threshold to activate color 3"],
		desc = L["Threshold to activate color 3"],
		max = 10,
		min = 1,
		step = .5,
		get = function ()
			return GridStatusPWShield.db.profile.alert_ws.threshold3
		end,
		set = function (v)
			GridStatusPWShield.db.profile.alert_ws.threshold3 = v
		end,
	},
	["color3"] = {
		type = "color",
		name = L["Color 3"],
		desc = L["Color 3"],
		hasAlpha = true,
		get = function ()
			local color = GridStatusPWShield.db.profile.alert_ws.color3
			return color.r, color.g, color.b, color.a
		end,
		set = function (r, g, b, a)
			local color = GridStatusPWShield.db.profile.alert_ws.color3
			color.r = r
			color.g = g
			color.b = b
			color.a = a or 1
		end,
	},
}

--}}}


function GridStatusPWShield:OnInitialize()
	self.super.OnInitialize(self)
	if englishClass == "PRIEST" then
		self:RegisterStatus("alert_pws", L["Buff: My Power Word: Shield"], pws_options)
		self:RegisterStatus("alert_ws", L["Debuff: My Weakened Soul"], ws_options)
	end
end

function GridStatusPWShield:OnEnable()
	if not GridRoster then
		RL = AceLibrary("Roster-2.1")
	end
	self:ScheduleRepeatingEvent("GPWS_Refresh", self.UpdateAll, GridStatusPWShield.db.profile.frequency, self)
end

function GridStatusPWShield:UpdateFrequency()
	self:CancelScheduledEvent("GPWS_Refresh");
	self:ScheduleRepeatingEvent("GPWS_Refresh", self.UpdateAll, GridStatusPWShield.db.profile.frequency, self)
end

function GridStatusPWShield:Reset()
	self.super.Reset(self)
end

local function updateUnit(self, gridid, unitid)
		local pwstime,wstime

		local now = GetTime()
		-- Find wanted buffs / debuffs
		for i=1,999 do
			local name, _, _, count, _, _, expirationTime, unitCaster, _ = UnitAura(unitid, i, "HELPFUL")
			if not name then break end
			local btime = expirationTime - now
			if name == spellNameCache["PWShield"] then
				if btime then pwstime = btime end
			end
		end
		for i=1,999 do
			local name, _, _, count, _, _, expirationTime, unitCaster, _ = UnitAura(unitid, i, "HARMFUL")
			if not name then break end
			local btime = expirationTime - now
			if name == spellNameCache["WeakenedSoul"] then
				if btime then wstime = btime end
			end		
		end

		--Power Word: Shield
		if pwstime then
			-- Add countdown and status
			local settings = self.db.profile.alert_pws
			local color = settings.color
			if pwstime <= settings.threshold2 then color = settings.color2 end
			if pwstime <= settings.threshold3 then color = settings.color3 end			
			self.core:SendStatusGained(gridid, "alert_pws",
				settings.priority,
				(settings.range and 40),
				color,
				tostring(math.floor(pwstime))
			)
		else
			if self.core:GetCachedStatus(gridid, "alert_pws") then self.core:SendStatusLost(gridid, "alert_pws") end
		end
		--Weakened Soul
		if wstime then
			-- Add countdown and status
			local settings = self.db.profile.alert_ws
			local color = settings.color
			if wstime <= settings.threshold2 then color = settings.color2 end
			if wstime <= settings.threshold3 then color = settings.color3 end			
			self.core:SendStatusGained(gridid, "alert_ws",
				settings.priority,
				(settings.range and 40),
				color,
				tostring(math.floor(wstime))
			)
		else
			if self.core:GetCachedStatus(gridid, "alert_ws") then self.core:SendStatusLost(gridid, "alert_ws") end
		end
end

function GridStatusPWShield:UpdateAll()

	if GridRoster then
		for guid, unitid in GridRoster:IterateRoster() do
			updateUnit(self, guid, unitid)
		end
	else
		for u in RL:IterateRoster(true) do
			local name = UnitName(u.unitid)
			if name then
				updateUnit(self, name, u.unitid)
			end
		end
	end
end
